import { Avatar, Modal } from "@arco-design/web-react";
import { createContext, useContext, useEffect, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";

import MBProtocalFactory from '../../../sdk/module/mb_constants'
import IMSDK from '../../../sdk'
import uuid from "../../../sdk/module/uuid";
import { MessageType } from "../../../domain/im/entity";
import { off } from "process";
import http from "../../../http";
import { clearVideo, updateVideoUserId } from "../../../store/features/user";
import { openMessage } from "../../../store/features/message";
import Countdown from "@arco-design/web-react/es/Statistic/countdown";
import Timer from "./Timer";



export const WebRtcModel: React.FC<any> = () => {
    const { visible } = useSelector((state: any) => state.user.value);
    return <>
        <Modal
            style={{ boxShadow: '0px 2px 10px rgba(0, 0, 0, 0.10)' }}
            className={`"shadow-2xl w-[350px] h-[600px] rounded-xl overflow-hidden"`}
            title={null}
            alignCenter={false}
            mask={true}
            visible={visible}
            footer={null}
            unmountOnExit={true}
            closeIcon={null}
            autoFocus={false}
            focusLock={false}
        >
            <WebRtcModelContent />

        </Modal>

    </>
}


export const WebRtcModelContent: React.FC<any> = () => {






    const dispatch = useDispatch();


    const [mainVideo, setMainVideo] = useState('local');
    const [localStream, setLocalStream] = useState<any>(null);
    const [remoteStream, setRemoteStream] = useState<any>(null);
    const [peerConnection, setPeerConnection] = useState<any>(null);
    const [fp, setFp] = useState<any>(null);
    const remoteVideoRef = useRef<any>(null);
    const localVideoRef = useRef<any>(null);



    const { videoUserId, visible, call } = useSelector((state: any) => state.user.value);
    const { candidate } = useSelector((state: any) => state.user.value);
    const { offer } = useSelector((state: any) => state.user.value);
    const { answer } = useSelector((state: any) => state.user.value);
    const { webrtc } = useSelector((state: any) => state.user.value);

    const toggleMainVideo = () => {
        setMainVideo(mainVideo === 'local' ? 'remote' : 'local');
    };

    const { list, current } = useSelector((state: any) => state.conversation.value);



    useEffect(() => {
        if (!visible) {
            setLocalStream(null);
            setRemoteStream(null);
            setPeerConnection(null);
            setState(false);
            dispatch(clearVideo(""))

        }
    }, [visible])



    const [user, setUser] = useState<any>(null);


    const [state, setState] = useState<any>(false);


    const [date, setDate] = useState<any>(null);





    useEffect(() => {
        const fetchUser = async () => {
            const response = await http.get(`/findUserById?id=${videoUserId}`);
            setUser(response.data);
        }
        fetchUser();

    }, [videoUserId])





    useEffect(() => {
        if (remoteVideoRef.current && remoteStream) {
            console.log('渲染视频', remoteStream)
            remoteVideoRef.current.srcObject = remoteStream;
            // remoteVideoRef.current.src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/gfeeh7pldnupqps/novel/welcome.mp4";
            remoteVideoRef.current.play(); // 确保视频开始播放
        }

    }, [remoteStream])



    useEffect(() => {

        // 对方接受了
        if (answer && peerConnection && call == "caller") {
            setDate(new Date());
            console.log("answer,peerConnection", answer, peerConnection)
            const str = answer.dataContent;
            const obj = JSON.parse(str);
            peerConnection.setRemoteDescription(new RTCSessionDescription(JSON.parse(obj.answer)))
                .then(() => {
                    console.log('远程描述设置成功');

                    setState(true);
                })
                .catch((error: any) => {
                    console.error('设置远程描述失败:', error);
                });

        }

    }, [answer, peerConnection, call])


    useEffect(() => {
        if (candidate && peerConnection) {
            console.log('收到对方的candidate', candidate)
            const str = candidate.dataContent;
            const obj = JSON.parse(str);
            peerConnection.addIceCandidate(new RTCIceCandidate(obj));

            if (call == "caller") {
                peerConnection.onicecandidate = (event: any) => {
                    if (event.candidate) {
                        console.log('New ICE candidate:', event.candidate);
                        let p: any = MBProtocalFactory.createCommonData({
                            dataContent: JSON.stringify(event.candidate),
                            from: IMSDK.getLoginInfo().loginUserId,
                            fp: uuid.v1(),
                            QoS: true,
                            to: videoUserId,
                            typeu: MessageType.Candidate
                        });
                        IMSDK.sendData(p);

                    }
                };
            }
        }
    }, [candidate, peerConnection])


    useEffect(() => {
        if (visible && videoUserId && call && webrtc) {
            const object = webrtc == "voice" ? { video: false, audio: true } : { video: true, audio: true };
            const startMediaStream = async () => {
                const stream = await navigator.mediaDevices.getUserMedia(object).then((stream: any) => {
                    setLocalStream(stream);

                    localVideoRef.current.srcObject = stream;
                    localVideoRef.current.play(); // 确保视频开始播放


                    // 创建 RTCPeerConnection
                    const pc = new RTCPeerConnection();
                    setPeerConnection(pc);



                    // 添加本地流到 RTCPeerConnection
                    stream.getTracks().forEach((track: any) => pc.addTrack(track, stream));

                    pc.ontrack = event => {
                        console.log("收到对方的视频流")
                        if (event.streams && event.streams[0]) {
                            setRemoteStream(event.streams[0]);
                        } else {
                            const inboundStream = new MediaStream();
                            inboundStream.addTrack(event.track);
                            setRemoteStream(inboundStream);
                        }
                    };


                    // 对方已经同意了
                    if (call == "answer" && offer) {
                        console.log(`call == "answer" && offer`, offer)
                        const messsage = JSON.parse(offer.dataContent);
                        console.log(messsage.offer);
                        pc.setRemoteDescription(new RTCSessionDescription(messsage.offer))
                            .then(() => {
                                return pc.createAnswer();
                            })
                            .then((answer: any) => {
                                return pc.setLocalDescription(answer);
                            })
                            .then(() => {
                                setState(true);
                                const answer = JSON.stringify(pc.localDescription);
                                setFp(offer.fp);
                                let str = JSON.stringify({ fp: offer.fp, answer: answer });
                                let p: any = MBProtocalFactory.createCommonData({
                                    dataContent: str,
                                    from: IMSDK.getLoginInfo().loginUserId,
                                    fp: uuid.v1(),
                                    QoS: true,
                                    to: videoUserId,
                                    typeu: MessageType.VideoAnswer
                                });
                                IMSDK.sendData(p);




                                // 向对方发送onice
                                pc.onicecandidate = event => {
                                    if (event.candidate) {
                                        console.log('New ICE candidate:', event.candidate);
                                        let p: any = MBProtocalFactory.createCommonData({
                                            dataContent: JSON.stringify(event.candidate),
                                            from: IMSDK.getLoginInfo().loginUserId,
                                            fp: uuid.v1(),
                                            QoS: true,
                                            to: videoUserId,
                                            typeu: MessageType.Candidate
                                        });
                                        IMSDK.sendData(p);

                                    }
                                };
                            })
                            .catch((error: any) => {
                                console.error('Error handling offer', error);
                            });

                    }


                    // 我想邀请对方 发起视频会话
                    if (call == "caller") {
                        pc.createOffer().then((offer) => {
                            pc.setLocalDescription(offer)
                            const fp = uuid.v1();
                            setFp(fp);
                            let p: any = MBProtocalFactory.createCommonData({
                                dataContent: JSON.stringify({
                                    state: 1,
                                    fp: fp,
                                    type: webrtc,
                                    offer: offer,

                                }),
                                from: IMSDK.getLoginInfo().loginUserId,
                                fp: fp,
                                QoS: true,
                                to: videoUserId,
                                typeu: MessageType.VideoOffer
                            });
                            IMSDK.sendData(p);
                        })
                            .catch(error => console.error('Error setting local description', error));
                    }


                })

                return stream;
            }


            startMediaStream();


            return () => {
                if (localStream) {
                    localStream.getTracks().forEach((track: any) => track.stop());
                }

                if (peerConnection) {
                    peerConnection.close();
                }
            };
        }
    }, [visible, videoUserId, call, offer, webrtc])

    const mainCss = 'object-cover w-[350px] h-[600px]';
    const minCss = 'overflow-hidden rounded-2xl  absolute top-3 left-3 object-cover w-[100px] h-[180px] cursor-pointer';

    return <div className="relative shadow-2xl w-[350px] h-[600px] rounded-xl overflow-hidden  bg-slate-600">
        <video className={mainVideo == "local" ? mainCss : minCss} autoPlay playsInline muted ref={localVideoRef}></video>
        <video onClick={toggleMainVideo} className={mainVideo == "local" ? minCss : mainCss} autoPlay playsInline muted ref={remoteVideoRef}></video>
        <div className="absolute bottom-8 w-[350px] h-[50px] flex flex-row justify-center items-center">
            <button onClick={() => {
                if (state) {
                    let p: any = MBProtocalFactory.createCommonData({
                        dataContent: fp,
                        from: IMSDK.getLoginInfo().loginUserId,
                        fp: uuid.v1(),
                        QoS: true,
                        to: videoUserId,
                        typeu: MessageType.VideoHangUp
                    });
                    IMSDK.sendData(p);
                    dispatch(updateVideoUserId({ visible: false }));

                    const fetchMessage = async () => {
                        const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                        dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
                    }
                    fetchMessage();
                } else {
                    let p: any = MBProtocalFactory.createCommonData({
                        dataContent: fp,
                        from: IMSDK.getLoginInfo().loginUserId,
                        fp: uuid.v1(),
                        QoS: true,
                        to: videoUserId,
                        typeu: MessageType.VideoCancel
                    });
                    IMSDK.sendData(p);
                    dispatch(updateVideoUserId({ visible: false }));


                    const fetchMessage = async () => {
                        const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                        dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
                    }

                    fetchMessage();
                }

            }} className="bg-red-500 text-white w-[60px] h-[60px] text-center rounded-full ">{state ? '挂断' : '取消'}</button>
        </div>
        {
            (user && !state) &&
            <div className="absolute top-12 w-[350px] flex flex-col justify-center items-center">
                <Avatar shape="square" size={75}>
                    {
                        user.userPortrait ? <img src={user.userPortrait}></img> : user.userName
                    }
                </Avatar>
                <span className="mt-[1px] text-white text-[27px] font-bold">{user.userName}</span>
                <span className="mt-[1px] text-white text-[14px]">正在等待对方接受邀请...</span>
            </div>
        }

        {
            (webrtc == "voice" && state) &&
            <>
                <div className="absolute top-2 w-[350px] flex flex-col justify-center items-center">
                   <Timer startTime={new Date().getTime()}></Timer>
                </div>
                <div className="absolute top-12 w-[350px] flex flex-col justify-center items-center">
                    <Avatar shape="square" size={75}>
                        {
                            user.userPortrait ? <img src={user.userPortrait}></img> : user.userName
                        }
                    </Avatar>
                    <span className="mt-[1px] text-white text-[27px] font-bold">{user.userName}</span>
                </div>
            </>
        }
    </div>;

}